home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Speccy ClassiX 1998
/
Speccy ClassiX 98.iso
/
amiga_system
/
the_aminet
/
dev
/
gcc
/
ixemulsrc.lha
/
ixemul-41.4
/
library
/
kern_time.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-05-28
|
6KB
|
208 lines
/*
* This file is part of ixemul.library for the Amiga.
* Copyright (C) 1991, 1992 Markus M. Wild
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* kern_time.c,v 1.1.1.1 1994/04/04 04:30:41 amiga Exp
*
* kern_time.c,v
* Revision 1.1.1.1 1994/04/04 04:30:41 amiga
* Initial CVS check in.
*
* Revision 1.1 1992/05/14 19:55:40 mwild
* Initial revision
*
*
* Since the code originated from Berkeley, the following copyright
* header applies as well. The code has been changed, it's not the
* original Berkeley code!
*/
/*
* Copyright (c) 1982, 1986, 1989 Regents of the University of California.
* All rights reserved.
*
* Redistribution is only permitted until one year after the first shipment
* of 4.4BSD by the Regents. Otherwise, redistribution and use in source and
* binary forms are permitted provided that: (1) source distributions retain
* this entire copyright notice and comment, and (2) distributions including
* binaries display the following acknowledgement: This product includes
* software developed by the University of California, Berkeley and its
* contributors'' in the documentation or other materials provided with the
* distribution and in all advertising materials mentioning features or use
* of this software. Neither the name of the University nor the names of
* its contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* @(#)kern_time.c 7.13 (Berkeley) 6/28/90
*/
#define KERNEL
#include "ixemul.h"
#include "kprintf.h"
#include <sys/time.h>
#define err_return(code) \
{ \
errno = code; \
KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno)); \
return errno == 0 ? 0 : -1; \
}
int
getitimer(u_int which, struct itimerval *itv)
{
if (which > ITIMER_PROF || !itv)
err_return (EINVAL);
Disable ();
*itv = u.u_timer[which];
Enable();
err_return (0);
}
int
setitimer(u_int which, const struct itimerval *itv, struct itimerval *oitv)
{
if (which > ITIMER_PROF)
err_return (EINVAL);
if (oitv && getitimer(which, oitv))
return -1;
if (itv == 0)
err_return (0);
if (itimerfix(&itv->it_value) || itimerfix(&itv->it_interval))
err_return (EINVAL);
Disable ();
u.u_timer[which] = *itv;
Enable ();
err_return (0);
}
/*
* Check that a proposed value to load into the .it_value or
* .it_interval part of an interval timer is acceptable, and
* fix it to have at least minimal value (i.e. if it is less
* than the resolution of the clock, round it up.)
*/
itimerfix(struct timeval *tv)
{
if (tv->tv_sec < 0 || tv->tv_sec > 100000000 ||
tv->tv_usec < 0 || tv->tv_usec >= 1000000)
err_return (EINVAL);
if (tv->tv_sec == 0 && tv->tv_usec != 0 && tv->tv_usec < ITIMER_RESOLUTION)
tv->tv_usec = ITIMER_RESOLUTION;
err_return (0);
}
/*
* Decrement an interval timer by a specified number
* of microseconds, which must be less than a second,
* i.e. < 1000000. If the timer expires, then reload
* it. In this case, carry over (usec - old value) to
* reducint the value reloaded into the timer so that
* the timer does not drift. This routine assumes
* that it is called in a context where the timers
* on which it is operating cannot change in value.
*/
/* on 0 return, send a signal to process */
int
itimerdecr (struct itimerval *itp, int usec) /* CALLED FROM INTERRUPT !! */
{
if (itp->it_value.tv_usec < usec)
{
if (itp->it_value.tv_sec == 0)
{
/* expired, and already in next interval */
usec -= itp->it_value.tv_usec;
goto expire;
}
itp->it_value.tv_usec += 1000000;
itp->it_value.tv_sec--;
}
itp->it_value.tv_usec -= usec;
usec = 0;
if (timerisset(&itp->it_value))
return (1);
/* expired, exactly at end of interval */
expire:
if (timerisset(&itp->it_interval))
{
itp->it_value = itp->it_interval;
itp->it_value.tv_usec -= usec;
if (itp->it_value.tv_usec < 0)
{
itp->it_value.tv_usec += 1000000;
itp->it_value.tv_sec--;
}
}
else
itp->it_value.tv_usec = 0; /* sec is already 0 */
return (0);
}
/*
* Add and subtract routines for timevals.
* N.B.: subtract routine doesn't deal with
* results which are before the beginning,
* it just gets very confused in this case.
* Caveat emptor.
*/
timevaladd(struct timeval *t1, const struct timeval *t2)
{
t1->tv_sec += t2->tv_sec;
t1->tv_usec += t2->tv_usec;
timevalfix(t1);
}
timevalsub(struct timeval *t1, const struct timeval *t2)
{
t1->tv_sec -= t2->tv_sec;
t1->tv_usec -= t2->tv_usec;
timevalfix(t1);
}
timevalfix(struct timeval *t1)
{
if (t1->tv_usec < 0) {
t1->tv_sec--;
t1->tv_usec += 1000000;
}
if (t1->tv_usec >= 1000000) {
t1->tv_sec++;
t1->tv_usec -= 1000000;
}
}